#include "GameWidget.h"
#include "ui_GameWidget.h"
#include "GlobalObject.h"

GameWidget::GameWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::GameWidget),gameScene(new QGraphicsScene(this))
    ,gameTimer(new QTimer(this)),mapManager(new MapManager(this)),player(nullptr)
{
    ui->setupUi(this);

    ui->gameView->setScene(gameScene);
    // 设置游戏视图
    ui->gameView->setScene(gameScene); // 将QGraphicsScene关联到QGraphicsView
    ui->gameView->setRenderHint(
        QPainter::Antialiasing);                 // 启用抗锯齿，提升图形质量
    ui->gameView->setBackgroundBrush(Qt::black); // 设置背景为黑色
    ui->gameView->setFixedSize(1280, 800);       // 固定视图大小（像素）
    gameScene->setSceneRect(0, 0, 1280, 800);    // 设置场景矩形区域（逻辑坐标）

    initMap();
    initPlayer();
    initNpc();

    // 连接游戏循环
    connect(gameTimer, &QTimer::timeout, this, &GameWidget::updateGame);

    // 设置焦点策略接收键盘事件
    setFocusPolicy(Qt::StrongFocus);

    // 记录初始时间
    lastUpdateTime = std::chrono::high_resolution_clock::now();
}

GameWidget::~GameWidget()
{
    delete ui;
}

void GameWidget::startGame() {
    gameTimer->start(16); // 60Fps
    lastUpdateTime = std::chrono::high_resolution_clock::now();
}

void GameWidget::pauseGame() {
    gameTimer->stop();
}

void GameWidget::resumeGame() {
    gameTimer->start();
    lastUpdateTime = std::chrono::high_resolution_clock::now();
}

void GameWidget::MapSwitch(const QString &name)
{
    //1. 移除
    gameScene->removeItem(player);
    for (int i = 0; i < NpcArray.size(); i++) {
        gameScene->removeItem(NpcArray[i]);
    }
    // 2. 清除场景中的其他图元
    gameScene->clear();

    this->mapManager->SwitchMap(name, this->gameScene);//切换

    //添加
    const MapData &map = mapManager->getCurrentMapData();
    player->setPos(map.pointBrith.x() * MapManager::tileSize,
                   map.pointBrith.y() * MapManager::tileSize);
    gameScene->addItem(player);
    gameScene->addItem(NpcArray[0]);

}

//重写事件处理函数

void GameWidget::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_W:
    case Qt::Key_Up:
        moveUp = true;
        break;
    case Qt::Key_S:
    case Qt::Key_Down:
        moveDown = true;
        break;
    case Qt::Key_A:
    case Qt::Key_Left:
        moveLeft = true;
        break;
    case Qt::Key_D:
    case Qt::Key_Right:
        moveRight = true;
        break;
    case Qt::Key_Shift:
        isSprinting = true;
        break;
    case Qt::Key_F:
        // 处理交互
        qDebug() << "Interact pressed";
        break;
    case Qt::Key_Escape:
    case Qt::Key_P:
        pauseGame();
        emit pauseRequested();
        break;
    default:
        QWidget::keyPressEvent(event);
    }
}

void GameWidget::keyReleaseEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_W:
    case Qt::Key_Up:
        moveUp = false;
        break;
    case Qt::Key_S:
    case Qt::Key_Down:
        moveDown = false;
        break;
    case Qt::Key_A:
    case Qt::Key_Left:
        moveLeft = false;
        break;
    case Qt::Key_D:
    case Qt::Key_Right:
        moveRight = false;
        break;
    case Qt::Key_Shift:
        isSprinting = false;
        break;
    default:
        QWidget::keyReleaseEvent(event);
    }
}



//private slots 函数

void GameWidget::updateGame()
{
    //qDebug()<<"update";
    // 计算时间增量
    float deltaTime = getDeltaTime();

    // 处理玩家输入
    player->handleInput(moveUp, moveDown, moveLeft, moveRight, isSprinting);

    // 更新玩家状态
    player->update(deltaTime);

    for (NPC *npc : std::as_const(NpcArray)) {
        if (gameScene->items().contains(npc))
            npc->update(deltaTime);
    }

    m_collidesTimer += deltaTime;
    if (m_collidesTimer >= COLLIDES_CHECK_INTERVAL)
    {
      m_collidesTimer = 0.0f;
      for (NPC *npc : std::as_const(NpcArray)) {
        if (gameScene->items().contains(npc)) {
              if (player->collidesWith(npc) && npc->isPokemonBattle()) {
                emit npcBattle(player->playerPokemon, npc->npcPokemon);
                qDebug() << "遇敌！！！";
              }
        }
      }
    }

    //ui->gameView->viewport()->update(); // 强制重绘
    // 更新视图中心跟随玩家
    ui->gameView->centerOn(player);

}

//private 函数

void GameWidget::initMap()
{
    QVector<QVector<int>> mapData = {
                                     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
                                     {1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1},
                                     {1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1},
                                     {1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,2,2,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1},
                                     {1,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,2,2,3,3,3,6,6,6,6,1},
                                     {1,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,2,2,3,3,3,6,6,6,6,1},
                                     {1,4,4,4,4,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,6,6,6,6,1},
                                     {1,4,4,4,4,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,6,6,6,6,1},
                                     {1,4,4,4,4,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,3,3,3,6,6,6,6,1},
                                     {1,4,4,4,4,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,3,3,3,6,6,6,6,1},
                                     {1,4,4,4,4,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,2,3,3,3,3,3,3,3,1},
                                     {1,4,4,4,4,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,2,3,3,3,3,3,3,3,1},
                                     {1,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,1},
                                     {1,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,1},
                                     {1,6,6,6,6,3,3,2,2,0,0,0,0,0,5,0,0,0,2,2,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,6,6,6,6,1},
                                     {1,6,6,6,6,3,3,2,2,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,6,6,6,6,1},
                                     {1,6,6,6,6,3,3,2,2,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,6,6,6,6,1},
                                     {1,6,6,6,6,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,6,6,6,6,1},
                                     {1,6,6,6,6,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,6,6,6,6,1},
                                     {1,6,6,6,6,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,6,6,6,6,1},
                                     {1,6,6,6,6,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,6,6,6,6,1},
                                     {1,6,6,6,6,6,6,6,6,6,6,6,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,6,6,6,6,6,6,6,6,6,6,6,1},
                                     {1,6,6,6,6,6,6,6,6,6,6,6,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,6,6,6,6,6,6,6,6,6,6,6,1},
                                     {1,6,6,6,6,6,6,6,6,6,6,6,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,6,6,6,6,6,6,6,6,6,6,6,1},
                                     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
                                     };

    mapManager->registerMap("Map", ":/background/find/tileset.png");
    mapManager->registerFixedMap("初始地图", ":/background/find/tileset.png",
                                 mapData);
    mapManager->loadMap("初始地图", gameScene);
}

void GameWidget::initPlayer()
{
    player = new PlayerCharacter(mapManager, this);

    // 加载玩家精灵表
    QPixmap playerSheet(":/character/find/player_sheet6.png");
    const int frameSize = 32;

    player->setAnimationFrames( // 下
        Character::DIR_DOWN,
        {playerSheet.copy(0 * frameSize, 0, frameSize, frameSize),
         playerSheet.copy(1 * frameSize, 0, frameSize, frameSize),
         playerSheet.copy(2 * frameSize, 0, frameSize, frameSize)});

    player->setAnimationFrames( // 左
        Character::DIR_LEFT,
        {playerSheet.copy(0 * frameSize, frameSize, frameSize, frameSize),
         playerSheet.copy(1 * frameSize, frameSize, frameSize, frameSize),
         playerSheet.copy(2 * frameSize, frameSize, frameSize, frameSize)});

    player->setAnimationFrames( // 右
        Character::DIR_RIGHT,
        {playerSheet.copy(0 * frameSize, frameSize * 2, frameSize, frameSize),
         playerSheet.copy(1 * frameSize, frameSize * 2, frameSize, frameSize),
         playerSheet.copy(2 * frameSize, frameSize * 2, frameSize, frameSize)});

    player->setAnimationFrames( // 上
        Character::DIR_UP,
        {playerSheet.copy(0 * frameSize, frameSize * 3, frameSize, frameSize),
         playerSheet.copy(1 * frameSize, frameSize * 3, frameSize, frameSize),
         playerSheet.copy(2 * frameSize, frameSize * 3, frameSize, frameSize)});

    // 设置玩家初始位置
    const MapData &map = mapManager->getCurrentMapData();
    player->setPos(map.pointBrith.x() * MapManager::tileSize,
                   map.pointBrith.y() * MapManager::tileSize);

    // 连接信号
    connect(player, &PlayerCharacter::wildPokemonEncountered,this,[this]() {
        qDebug() << "Wild Pokemon encountered!";
        emit wildBattle(player->playerPokemon);
    });

    gameScene->addItem(player);

    // 视图跟随玩家
    ui->gameView->centerOn(player);
}

void GameWidget::initNpc()
{

    //加载图像
    QPixmap npcSheet(":/character/find/player_sheet7.png") ;
    const int frameSize = 32;

    //npc1
    NPC *npc1 = new NPC(mapManager, this);
    npc1->setBehaviorType(NPC::BehaviorType::StaticNpc);

    npc1->setAnimationFrames(
        Character::DIR_DOWN,
        {npcSheet.copy(0 * frameSize, 0, frameSize, frameSize),
         npcSheet.copy(1 * frameSize, 0, frameSize, frameSize),
         npcSheet.copy(2 * frameSize, 0, frameSize, frameSize)});

    npc1->setPos(13 * MapManager::tileSize, 10 * MapManager::tileSize);
    gameScene->addItem(npc1);
    NpcArray.append(npc1);

    npc1->npcPokemon.append(MyNS::playerPokemon21);

    //npc2;
    NPC *npc2 = new NPC(mapManager, this);
    npc2->setBehaviorType(NPC::BehaviorType::Wandering);

    QRectF movementArea(5 * MapManager::tileSize,  // x
                        5 * MapManager::tileSize,  // y
                        10 * MapManager::tileSize, // width
                        8 * MapManager::tileSize   // height
                        );
    npc2->setMovementArea(movementArea);

    npcSheet.load(":/character/find/player_sheet8.png");

    npc2->setAnimationFrames( // 下
        Character::DIR_DOWN,
        {npcSheet.copy(0 * frameSize, 0, frameSize, frameSize),
         npcSheet.copy(1 * frameSize, 0, frameSize, frameSize),
         npcSheet.copy(2 * frameSize, 0, frameSize, frameSize)});

    npc2->setAnimationFrames( // 左
        Character::DIR_LEFT,
        {npcSheet.copy(0 * frameSize, frameSize, frameSize, frameSize),
         npcSheet.copy(1 * frameSize, frameSize, frameSize, frameSize),
         npcSheet.copy(2 * frameSize, frameSize, frameSize, frameSize)});

    npc2->setAnimationFrames( // 右
        Character::DIR_RIGHT,
        {npcSheet.copy(0 * frameSize, frameSize * 2, frameSize, frameSize),
         npcSheet.copy(1 * frameSize, frameSize * 2, frameSize, frameSize),
         npcSheet.copy(2 * frameSize, frameSize * 2, frameSize, frameSize)});

    npc2->setAnimationFrames( // 上
        Character::DIR_UP,
        {npcSheet.copy(0 * frameSize, frameSize * 3, frameSize, frameSize),
         npcSheet.copy(1 * frameSize, frameSize * 3, frameSize, frameSize),
         npcSheet.copy(2 * frameSize, frameSize * 3, frameSize, frameSize)});

    QPointF startPos(7 * MapManager::tileSize, 7 * MapManager::tileSize);
    npc2->setPos(startPos);
    gameScene->addItem(npc2);
    NpcArray.append(npc2);

    npc2->npcPokemon.append(MyNS::playerPokemon52);
}

float GameWidget::getDeltaTime()
{
    auto currentTime = std::chrono::high_resolution_clock::now();
    float deltaTime = std::chrono::duration<float>(currentTime - lastUpdateTime).count();
    lastUpdateTime = currentTime;
    return (deltaTime > 0.1f) ? 0.1f : deltaTime; //限制最大deltaTime避免调试暂停时出现异常移动


}


